<?php

/**
 * Created by PhpStorm.
 * User: gxk
 * Date: 2019/5/7
 * Time: 16:45
 */
class WebsocketTest
{
    public $server;
    public $redis;

    public function __construct()
    {
        //设置redis作为关系绑定介质
        $this->redis = new \Redis();
        $this->redis->pconnect('127.0.0.1', 6379, 4);
        $this->server = new Swoole\WebSocket\Server("0.0.0.0", 9502);
        $this->server->set([
            'worker_num' => 4,
            'daemonize'  => 0
        ]);
        $this->server->on('open', function (swoole_websocket_server $server, $request) {
            echo "server: handshake success with fd{$request->fd}\n";
            //建立fd与会员的映射关系
            $this->redis->hSet('onlinelist', $request->fd, $request->cookie['member_id']);
            //给所有人推送在线信息
            $this->push_member_status();

        });
        $this->server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
//            echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
//            $server->push($frame->fd, "this is server");
            $receData = json_decode($frame->data, 1);


            //单聊正在输入
            if ($receData['type'] == 'isinput') {
                //获取fd
                $fdlist = $this->redis->hGetAll('onlinelist');
                foreach ($fdlist as $fd => $uid) {
                    if ($uid == $receData['rece']) {
                        if ($this->server->isEstablished($fd)) {
                            $this->server->push($fd, $frame->data);
                        }
                    }
                }
            }

//            foreach ($this->server->connections as $fd) {
//                // 需要先判断是否是正确的websocket连接，否则有可能会push失败
//                if ($this->server->isEstablished($fd)) {
//                    $this->server->push($fd, json_encode([
//                        'type'=>'message',
//                        'data'=>$frame->data
//                    ]));
//                }
//            }
        });
        $this->server->on('close', function ($ser, $fd) {
            echo "client {$fd} closed\n";
            //断开fd与会员的映射关系
            if ($this->redis->hExists('onlinelist', $fd)) {
                echo '进入清理过程';
                $this->redis->hDel('onlinelist', $fd);
            }
            //给所有人推送在线信息
            $this->push_member_status();
        });
        $this->server->on('request', function ($request, $response) {
            //去除chrome的ico
            $uri = $request->server['request_uri'];
            if ($uri == '/favicon.ico') {
                $response->status(404);
                $response->end();
            }
            $post = $request->post;
            //如果是群发的信息
            if ($post['rece_user_id'] == 0) {
                // 接收http请求从get获取message参数的值，给用户推送
                // $this->server->connections 遍历所有websocket连接用户的fd，给所有用户推送
                foreach ($this->server->connections as $fd) {
                    // 需要先判断是否是正确的websocket连接，否则有可能会push失败
                    if ($this->server->isEstablished($fd)) {
                        $this->server->push($fd, json_encode([
                            'type' => 'message',
                            'data' => $post
                        ]));
                    }
                }

            }
            //如果是单发的信息
            if ($post['rece_user_id'] > 0) {
                //根据rece_user_id取到fd
                //目前模式是多客户端共享,所以得到的结果是一个集合
                $fdlist = $this->redis->hGetAll('onlinelist');
                foreach ($fdlist as $fds => $uid) {
                    if ($uid == $post['rece_user_id'] || $uid == $post['chat_user_id']) {
                        // 需要先判断是否是正确的websocket连接，否则有可能会push失败
                        if ($this->server->isEstablished($fds)) {
                            $this->server->push($fds, json_encode([
                                'type' => 'message',
                                'data' => $post
                            ]));
                        }
                    }
                }
            }
            $response->end(json_encode([
                'status'  => 200,
                'message' => 'success'
            ]));
        });
        $this->server->start();
    }

    //会员在线状态
    public function push_member_status()
    {
//        var_export($this->redis->hGetAll('onlinelist'));
        foreach ($this->server->connections as $fd) {
//            echo $fd;
//            echo PHP_EOL;
            // 需要先判断是否是正确的websocket连接，否则有可能会push失败
            if ($this->server->isEstablished($fd) && $this->server->exist($fd)) {
                $this->server->push($fd, json_encode([
                    'type' => 'onlineList',
                    'data' => array_unique($this->redis->hGetAll('onlinelist'))
                ]));
            }
        }
    }
}

new WebsocketTest();